package main
import (
	"fmt"
)
//结构体方法（方法与结构体类型绑定）   除了多了个类型对象实参，其他都与普通函数相同，比如传参，返回值等等！
type Person struct{
	Age int
}
//以下的方法就是结构体专属方法！
func (p Person )test(){    //(a A) 体现了这个方法只能给A类型使用！！！
	p.Age = 200
	fmt.Println("test() : ",p.Age)
}

//通过指针类型的绑定，可以提高效率无需值拷贝！
func (p *Person)test2(){  //当类型对象是指针类型时，则调用该方法的对象传入的是地址~
	(*p).Age = 400  //  (*p).Age == p.Age
	fmt.Println("test()2 : ",p.Age)
	fmt.Printf("p address : %p\n",p)
	
}
//------------------------------------------------------------------------------------------------------------------
//其他数据类型也是可以拥有对应的绑定方法！但是需要自定义类型如下
type integer int
func (n integer)test3(){
	fmt.Println("test3() : ",n)
}
func (n *integer)test4(){
	*n = 100
	fmt.Println("test3() : ",*n)
}

//--------------------------------------------------------------------------- main -----------------------------------------
func main(){
	var person Person 
	person.Age = 100
	person.test()   //调用test方法的时候，会自动将自己这个对象传给方法中的（p Person）中,并且传这个对象的时候是值拷贝！！！
	//所以虽然方法里面修改了Age，但是在main里面的对象的Age不变
	fmt.Println("main() : ",person.Age)
	//---------------------------------------------------------------------------
	//当类型方法的参数是指针时，则是引用类型，这样就会在main中发生与函数中同样的变化
	(&person).test2()   //若是指针，也可以直接写person.test2()
	fmt.Println("main() : ",person.Age)
	fmt.Printf("person address : %p\n",&person)
	//---------------------------------------------------------------------------------
	//int类型绑定的方法
	var num integer = 10
	num.test3()
	num.test4()
	fmt.Println("main() : ",num)


	//--------------------------------------------------String()-------------------------------
	stu := Student{
		Name : "FMX",
		Age : 22,
	}
	//当我们默认输出stu实例的时候就会自动调用String方法
	//由于形参是指针所以传入地址
	fmt.Println(&stu)
	fmt.Printf("stu address~ : %p",&stu)
}
//----------------------------------------------------------------------------------------------------------------------
//如果一个类型实现了String()这个方法，那么fmt.Println默认会调用这个变量的String()进行输出
type Student struct{
	Name string
	Age int
}
//给*Student实现方法String()  //类似java里面的toString()
func (stu *Student)String() string{
	str := fmt.Sprintf("Name=[%v] Age=[%v]",stu.Name,stu.Age)
	return str
}